package com.cg.service.Impl;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cg.Dto.*;
import com.cg.common.StringConstant;
import com.cg.entity.Personnel;
import com.cg.mapper.PersonnelMapper;
import com.cg.result.PageDTO;
import com.cg.result.PageVO;
import com.cg.result.R;
import com.cg.service.PersonnelService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cg.util.JwtUtil;
import com.cg.util.Md5Utils;
import com.cg.util.PhoneNumberUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.Max;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import org.springframework.beans.BeanUtils;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lhy
 * @since 2024-12-26
 */
@Service
public class PersonnelServiceImpl extends ServiceImpl<PersonnelMapper, Personnel> implements PersonnelService {
    private static final Logger logger = LoggerFactory.getLogger(PersonnelServiceImpl.class);
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private JwtUtil jwtUtil;
    @Resource
    private PersonnelMapper personnelMapper;
    @Override
    public R login(LoginDto loginDto) {
        LambdaQueryWrapper<Personnel> queryWrapper = new LambdaQueryWrapper<Personnel>()
                .eq(Personnel::getLoginAccount, loginDto.getLoginAccount());
        Personnel personnel = this.getOne(queryWrapper);
        if (ObjectUtils.isEmpty(personnel)) {
            return R.Failed(StringConstant.ACCOUNTISNULL);
        }
        // 检查账号状态是否为0（禁用状态）
        if (!personnel.getStatus()) { // 假设 status 字段是 int 类型
            return R.Failed(StringConstant.STATUSISNOTUSE); // 返回账号禁用的消息
        }
        // 使用安全的哈希算法进行密码比较
        if (!personnel.getPassword().equals(Md5Utils.hash(loginDto.getPassword()))) {
            return R.Failed(StringConstant.PASSWORDERROR);
        }
        // 准备 token 的 payload 数据
        Map<String, String> map = new HashMap<>();
        map.put("username", personnel.getPersonName());
        map.put("account", personnel.getLoginAccount());
        try {

            // 直接调用静态方法
            String token = jwtUtil.createToken(map);
            // 返回带有 token 的响应
            return R.Success(token);
        } catch (Exception e) {
            return R.Failed(StringConstant.SYSTEMERROR);
        }
    }
    @Override
    public R getAccount(HttpServletRequest request) {
         ;
        String token = request.getHeader(StringConstant.AUTHORIZATION);
        if (token == null || token.isEmpty()) {
            return R.Failed(StringConstant.TOKENISBULL);
        }
        try {
            // 验证 token 并获取解码后的 JWT 信息
            DecodedJWT tokenInfo;
            tokenInfo = jwtUtil.verifyToken(token);
            String username = tokenInfo.getClaim("username").asString();
            // 返回成功响应，包含用户名
            return R.Success(username);
        } catch (Exception e) {
            return R.Failed(StringConstant.TOKENISNOUSE);
        }
    }
    @Override
    public R searchuser(SearchUserDto searchUserDto) {
        // 创建分页对象
        Page<Personnel> pages = new Page<>(searchUserDto.getPageNumber(), searchUserDto.getPageSize());
        // 构建查询条件
        LambdaQueryWrapper<Personnel> wrapper = new LambdaQueryWrapper<Personnel>()
                .like(StringUtils.isNotBlank(searchUserDto.getPersonName()), Personnel::getPersonName, searchUserDto.getPersonName())
                .eq(StringUtils.isNotBlank(searchUserDto.getPhoneNumber()), Personnel::getPhoneNumber, searchUserDto.getPhoneNumber())
                .eq(searchUserDto.getStatus() != null, Personnel::getStatus, searchUserDto.getStatus());
        // 执行分页查询
        Page<Personnel> page = this.page(pages, wrapper);
        // 检查是否有数据
        if (page.getRecords().isEmpty()) {
            return R.Failed ("No matching records found");
        }
        // 将分页结果转换为PageVO
        PageVO<Personnel> pagevo = new PageVO<>();
        BeanUtils.copyProperties(page, pagevo);
        // 返回成功响应
        return R.Success (pagevo);
    }
    @Override
    public R<?> insertuser(InsertUserDto insertUserDto) {
        Personnel personnel = new Personnel();
        BeanUtils.copyProperties(insertUserDto, personnel);
        // 使用工具类的方法来验证手机号
        if (!PhoneNumberUtil.isValidChinaPhoneNumber(personnel.getPhoneNumber())) {
            return R.Failed(StringConstant.INVALID_PHONE_NUMBER); // 返回错误信息
        }

        // 生成 loginAccount
        personnel.setLoginAccount(generateLoginAccount());
        // 设置默认密码为手机号后6位
        if (!StringUtils.isEmpty(personnel.getPhoneNumber())) {
            String defaultPassword = personnel.getPhoneNumber().substring(Math.max(0, personnel.getPhoneNumber().length() - 6));
            personnel.setPassword(Md5Utils.hash(defaultPassword)); // 加密密码
        } else {
            return R.Failed(StringConstant.PHONE_NUMBER_REQUIRED); // 或者抛出异常
        }
        // 确保 personName 已设置
        if (StringUtils.isEmpty(personnel.getPersonName())) {
            return R.Failed(StringConstant.PERSON_NAME_REQUIRED); // 或者抛出异常
        }
        return save(personnel) ? R.Success(StringConstant.INSERTSUCCESS) : R.Failed(StringConstant.INSERTFAILD);
    }
    @Override
    public R<?> updateperson(UpdateUserDto updateUserDto) {
        //根据登录账号判断用户是否存在
        Personnel personnel = this.getOne (new LambdaQueryWrapper<Personnel> ()
                .eq (Personnel::getLoginAccount,updateUserDto.getLoginAccount ()));
        if(ObjectUtils.isEmpty (personnel))
        {
            return R.Failed (StringConstant.USERNOTFOUND);
        }
        // 使用工具类的方法来验证新手机号
        if (!StringUtils.isEmpty(updateUserDto.getPhoneNumber()) && !PhoneNumberUtil.isValidChinaPhoneNumber(updateUserDto.getPhoneNumber())) {
            return R.Failed(StringConstant.INVALID_PHONE_NUMBER); // 返回错误信息
        }
        //设置更新条件
        LambdaUpdateWrapper<Personnel> wrapper =new LambdaUpdateWrapper<Personnel> ()
                .set (Personnel::getPersonName,updateUserDto.getPersonName ())
                .set (Personnel::getPhoneNumber,updateUserDto.getPhoneNumber ())
                .set (Personnel::getStatus,updateUserDto.getStatus ())
                .eq (Personnel::getLoginAccount,updateUserDto.getLoginAccount ());
        //判断手机号有没有更改,如果更改了就要将密码也进行更新
        if(!StringUtils.equals (personnel.getPhoneNumber (),updateUserDto.getPersonName ()))
        {
            String newPassword = updateUserDto.getPhoneNumber ().substring (Math.max (0,updateUserDto.getPhoneNumber ().length ()-6));
            wrapper.set (Personnel::getPassword,Md5Utils.hash (newPassword));
        }
        boolean update = this.update ( wrapper );
        if(update)
        {
            return R.Success (StringConstant.UPDATESUCCESS);
        }
        else {
            return R.Failed (StringConstant.UPDATEFAILED);
        }
    }
    @Override
    public R<?> updatestatus(UpdateStatusDto updateStatusDto) {
       LambdaUpdateWrapper<Personnel> wrapper =new LambdaUpdateWrapper<Personnel> ()
               .set (Personnel::getStatus,updateStatusDto.getStatus ())
               .eq (Personnel::getLoginAccount,updateStatusDto.getLoginAccount ());
        boolean update = this.update ( wrapper );
        if (update)
        {
            return  R.Success (StringConstant.UPDATESUCCESS);
        }
        else {
            return R.Failed (StringConstant.UPDATEFAILED);
        }
    }
    // 工具方法：生成 loginAccount
    private String generateLoginAccount() {
        // 获取当前最大的序号
        Integer maxId = personnelMapper.selectMaxId();
        if (maxId == null) {
            maxId = 0;
        }
        // 根据规则生成 loginAccount
        return String.format("YZ%03d", maxId + 1);
    }
}
